home *** CD-ROM | disk | FTP | other *** search
/ MacTech 1 to 12 / MacTech-vol-1-12.toast / Source / SpriteWorld 2.0 ƒ / SpriteWorld Examples / SpriteTest / SpriteTest.c < prev    next >
Encoding:
Text File  |  1996-10-11  |  25.8 KB  |  991 lines  |  [TEXT/KAHL]

  1. ///--------------------------------------------------------------------------------------
  2. // SpriteTest.c
  3. //
  4. // By: Tony Myles
  5. //
  6. // Extensive modifications by Karl Bunker
  7. //
  8. ///--------------------------------------------------------------------------------------
  9.  
  10. #include <Timer.h>
  11.  
  12. #include <SWIncludes.h>            // Automatically include all SpriteWorld.h files
  13.  
  14. #include <SWGameUtils.h>
  15. #include <SWDitherDown.h>
  16. #include "DialogUtils.h"
  17. #include "SpriteTest.h"
  18. /*
  19. #if __MWERKS__
  20. #include <profiler.h>
  21. #endif
  22. */
  23. #define kBlitterTest false
  24.  
  25. #define kWorldRectInset 0        // modify to test SpriteWorld rect less than window size
  26.  
  27. Boolean            gGlobesVisible;
  28. Boolean            gTitleVisible;
  29. Boolean            gCollisionDetection;
  30. ProcType        gWhichSpriteProc;
  31. ProcType        gWhichOffscreenProc;
  32. ProcType        gWhichScreenProc;
  33. short             gMoveDelta;
  34. SpritePtr        gMasterGlobeSprite = NULL;
  35.  
  36.  
  37. /******************** SetupSWStuff ********************/
  38. OSErr SetupSWStuff(
  39.     SpriteTestPtr* spriteTestP,
  40.     CWindowPtr srcWindowP)
  41. {
  42.     OSErr                 err = noErr;
  43.     SpriteTestPtr         tempSpriteTestP;
  44.     SpriteWorldPtr         spriteWorldP = NULL;
  45.     SpriteLayerPtr         globeSpriteLayerP;
  46.     SpritePtr             globeSpriteArray[kNumberOfGlobeSprites];
  47.     SpritePtr             titleSpriteP;
  48.     SpritePtr             twoSpriteP;
  49.     PixPatHandle         pixPatH = NULL;
  50.     short                 spriteNum;
  51.     short                 oldResRefNum, curResRefNum;
  52.     Rect                 windowRect, worldRect;
  53.  
  54.     
  55.     *spriteTestP = NULL;
  56.  
  57.     SetPort((GrafPtr)srcWindowP);
  58.     
  59.     
  60.     windowRect = srcWindowP->portRect; 
  61.     worldRect = windowRect;
  62.     InsetRect( &worldRect, kWorldRectInset, kWorldRectInset );
  63.     
  64.     ShowWindow( (WindowPtr)srcWindowP );
  65.     TextFont( systemFont );
  66.     TextSize( 12 );
  67.     MoveTo( 40, 80 );
  68.     DrawString( "\pLoading Sprites... please wait" );
  69.     
  70.     tempSpriteTestP = (SpriteTestPtr)NewPtrClear((Size)sizeof(SpriteTestRec));
  71.     
  72.     {
  73.             // create the sprite world
  74.         (void)SWCreateSpriteWorldFromWindow(&spriteWorldP, srcWindowP, &worldRect, NULL);
  75.     }
  76.  
  77.     if (SWStickyError() == noErr)
  78.     {
  79.         tempSpriteTestP->spriteWorldP = spriteWorldP;
  80.         
  81.             // create the sprite layer
  82.         (void)SWCreateSpriteLayer(&globeSpriteLayerP);
  83.         tempSpriteTestP->globeSpriteLayerP = globeSpriteLayerP;
  84.     }
  85.  
  86.     if (SWStickyError() == noErr)
  87.     {
  88.         oldResRefNum = CurResFile();
  89.         curResRefNum = OpenResFile("\pSpriteTest Frames");
  90.         SWSetStickyIfError( ResError() );
  91.     }
  92.  
  93.     if (SWStickyError() == noErr)
  94.     {
  95.         UseResFile(curResRefNum);
  96.  
  97.         (void)SWCreateSpriteFromSinglePict(
  98.             spriteWorldP,
  99.             &gMasterGlobeSprite,
  100.             NULL,
  101.             kBaseResID,
  102.             kBaseResID+1,
  103.             kGlobeHeight,
  104.             kFatMask);
  105.  
  106.         (void)SWCreateSpriteFromSinglePict(
  107.             spriteWorldP,
  108.             &twoSpriteP,
  109.             NULL,
  110.             kBaseResID+2,
  111.             kBaseResID+2,
  112.             kTwoHeight,
  113.             kFatMask);
  114.         
  115.         if (SWStickyError() == noErr)
  116.         {
  117.             if ( spriteWorldP->pixelDepth < 8 )
  118.             {
  119.                 DitherDownPict( kBaseResID+2, twoSpriteP->sharedPictGWorld );
  120.                 LowerMaskDepth( kBaseResID+2, twoSpriteP->sharedMaskGWorld );
  121.             }
  122.             SWSetSpriteFrameTime( twoSpriteP, kGlobeSpriteFrameTime*4 );
  123.             SWSetSpriteFrameRange( twoSpriteP, 0, kNumberOfTwoFrames - 1);
  124.             SWSetSpriteFrameProc( twoSpriteP, TwoSpriteFrameProc );
  125.         }
  126.         UseResFile(oldResRefNum);
  127.         CloseResFile(curResRefNum);
  128.     }
  129.  
  130.     if (SWStickyError() == noErr)
  131.     {
  132.         if ( spriteWorldP->pixelDepth == 8 )
  133.             (void)SWCompileSprite( gMasterGlobeSprite );
  134.             // master globe sprite isn't added to any layer, so we have to lock it separately
  135.         SWLockSprite( gMasterGlobeSprite);
  136.     }
  137.  
  138.     if (SWStickyError() == noErr)
  139.     {
  140.             
  141.         for (spriteNum = 0; spriteNum < kNumberOfGlobeSprites; spriteNum++)
  142.         {
  143.             (void)SWCloneSprite(gMasterGlobeSprite, globeSpriteArray + spriteNum, NULL);
  144.             tempSpriteTestP->globeSpriteArray[spriteNum] = globeSpriteArray[spriteNum];
  145.         }
  146.     
  147.     }
  148.     
  149.     if (SWStickyError() == noErr)
  150.     {
  151.         (void)SWCreateSpriteFromPictResource( 
  152.             spriteWorldP,
  153.             &titleSpriteP, 
  154.             NULL, 
  155.             kBaseResID, 
  156.             kBaseResID, 
  157.             1, 
  158.             kFatMask);
  159.         
  160.         if ( spriteWorldP->pixelDepth < 8 )
  161.         {
  162.             DitherDownPict( kBaseResID, titleSpriteP->frameArray[0]->framePort );
  163.             LowerMaskDepth( kBaseResID, titleSpriteP->frameArray[0]->maskPort );
  164.         }
  165.         tempSpriteTestP->titleSpriteP = titleSpriteP;
  166.         tempSpriteTestP->twoSpriteP = twoSpriteP;
  167.         
  168.         *spriteTestP = tempSpriteTestP;
  169.         
  170.         for (spriteNum = 0; spriteNum < kNumberOfGlobeSprites; spriteNum++)
  171.         {
  172.             if (spriteNum == (kNumberOfGlobeSprites / 2))
  173.             {
  174.                 SWAddSprite(globeSpriteLayerP, titleSpriteP);
  175.                 SWAddSprite(globeSpriteLayerP, twoSpriteP);
  176.             }
  177.             SWAddSprite(globeSpriteLayerP, globeSpriteArray[spriteNum]);
  178.         }
  179.         
  180.  
  181.         SWAddSpriteLayer(spriteWorldP, globeSpriteLayerP);
  182.  
  183.  
  184.         SWLockSpriteWorld(spriteWorldP);
  185.     
  186.         SWSetPortToBackground(spriteWorldP);
  187.         EraseRect( &spriteWorldP->backRect );
  188.         
  189.         if ( spriteWorldP->pixelDepth >= 8 )
  190.         {
  191.             pixPatH = GetPixPat(kBackDropPixPatID);
  192.             if ( pixPatH != NULL )
  193.             {
  194.                 FillCRect(&spriteWorldP->backRect, pixPatH);
  195.                 DisposePixPat(pixPatH);
  196.             }
  197.         }
  198.         else
  199.             FillRect(&spriteWorldP->backRect, &qd.ltGray);
  200.         
  201.         SWSetPortToWindow(spriteWorldP);
  202.         
  203.         SetupSpriteWorldElements(tempSpriteTestP);
  204.     }
  205.     if ( SWStickyError() != noErr)
  206.     {
  207.         DisposeSWStuff(tempSpriteTestP);
  208.     }
  209.  
  210.     return SWStickyError();
  211. }
  212.         
  213.  
  214. /******************** DisposeSWStuff ********************/
  215. void DisposeSWStuff(
  216.     SpriteTestPtr spriteTestP)
  217. {    
  218.     if (spriteTestP != NULL)
  219.     {
  220.         if (spriteTestP->spriteWorldP != NULL)
  221.         {
  222.             SWDisposeSpriteWorld(spriteTestP->spriteWorldP);
  223.         }
  224.             // gMasterGlobeSprite is not added to any layer, 
  225.             // so SWDisposeSpriteWorld won't dispose of it
  226.         if ( gMasterGlobeSprite != NULL )
  227.         {
  228.             SWDisposeSprite( gMasterGlobeSprite );
  229.         }
  230.         DisposePtr((Ptr)spriteTestP);
  231.     }
  232. }
  233.  
  234.  
  235. /******************** SetupSpriteWorldElements ********************/
  236. void SetupSpriteWorldElements(
  237.     SpriteTestPtr spriteTestP)
  238. {
  239.     register         long spriteNum;
  240.     Rect             moveBoundsRect;
  241.     Rect            titleDestRect;
  242.     
  243.  
  244.     moveBoundsRect = spriteTestP->spriteWorldP->backRect;
  245.     
  246.         // set up the globe sprites
  247.     gMoveDelta = 0;
  248.     for (spriteNum = 0; spriteNum < kNumberOfGlobeSprites; spriteNum++)
  249.     {
  250.         SetupGlobeSprite(spriteTestP->globeSpriteArray[spriteNum], &moveBoundsRect,
  251.                 GetRandom(moveBoundsRect.left, moveBoundsRect.right),
  252.                 GetRandom(moveBoundsRect.top, moveBoundsRect.bottom));
  253.     }
  254.  
  255.         // set up the title sprites
  256.     titleDestRect = spriteTestP->titleSpriteP->destFrameRect;
  257.  
  258.     CenterRect( &titleDestRect, &moveBoundsRect );
  259.     OffsetRect( &titleDestRect, -(kTwoHeight + 2 ), 0 );
  260.     SWSetSpriteLocation(spriteTestP->titleSpriteP, titleDestRect.left, titleDestRect.top );
  261.     
  262.     SWSetSpriteLocation(spriteTestP->twoSpriteP, titleDestRect.right, titleDestRect.top-7 );
  263.     
  264.     SWSetSpriteWorldMaxFPS( spriteTestP->spriteWorldP, 30 );
  265. //    SWSyncSpriteWorldToVBL( spriteTestP->spriteWorldP, true );
  266.  
  267.     gGlobesVisible = true;
  268.     gTitleVisible = true;
  269.     gCollisionDetection = false;
  270.     gWhichSpriteProc = kCopyBitsProc;
  271.     gWhichOffscreenProc = kCopyBitsProc;
  272.     gWhichScreenProc = kCopyBitsProc;
  273. }
  274.  
  275.  
  276. /******************** SetupGlobeSprite ********************/
  277.  
  278. void SetupGlobeSprite(
  279.     SpritePtr globeSpriteP,
  280.     Rect *moveBoundsRect,
  281.     short horizLocation,
  282.     short vertLocation)
  283. {
  284.     Rect tempBoundsRect;
  285.     short horizMoveDelta;
  286.     short vertMoveDelta;
  287.  
  288.     gMoveDelta++;
  289.     if ( gMoveDelta > 17 )
  290.         gMoveDelta = 1;
  291.  
  292.     tempBoundsRect = *moveBoundsRect;
  293.  
  294.     horizMoveDelta = gMoveDelta;    //GetRandom(2, 6);
  295.     vertMoveDelta =    gMoveDelta;        //GetRandom(2, 6);
  296.  
  297.     if (GetRandom(0, 1) == 0)
  298.     {
  299.         horizMoveDelta = -horizMoveDelta;
  300.     }
  301.  
  302.     if (GetRandom(0, 1) == 0)
  303.     {
  304.         vertMoveDelta = -vertMoveDelta;
  305.     }
  306.  
  307.         // set the sprite’s movement characteristics
  308.     SWSetSpriteMoveBounds(globeSpriteP, &tempBoundsRect);
  309.     SWSetSpriteMoveDelta(globeSpriteP, horizMoveDelta, vertMoveDelta);
  310.     SWSetSpriteMoveProc(globeSpriteP, GlobeSpriteMoveProc);
  311.     SWSetSpriteMoveTime(globeSpriteP, kGlobeSpriteMoveTime);
  312.  
  313.     SWSetSpriteFrameTime(globeSpriteP, kGlobeSpriteFrameTime);
  314.     SWSetSpriteFrameRange(globeSpriteP, 0, kNumberOfGlobeFrames - 1);
  315.     SWSetSpriteFrameAdvance(globeSpriteP, GetRandom(0, 1) ? -1 : 1);
  316.  
  317.         // three to try:
  318.         // PixelBounceCollideProc, -- 8 bits only!
  319.         // RegionBounceCollideProc,
  320.         // RadiusBounceCollideProc
  321.     SWSetSpriteCollideProc(globeSpriteP, RegionBounceCollideProc);
  322.  
  323.         // set the sprite’s initial location
  324.     SWSetSpriteLocation(globeSpriteP, horizLocation, vertLocation);
  325. }
  326.  
  327.  
  328. /******************** SpriteTestIdle ********************/
  329. void SpriteTestIdle(
  330.     SpriteTestPtr spriteTestP )
  331. {
  332.     if (gCollisionDetection)
  333.     {
  334.         SWCollideSpriteLayer(spriteTestP->spriteWorldP, 
  335.             spriteTestP->globeSpriteLayerP, spriteTestP->globeSpriteLayerP);
  336.     }
  337.     SWProcessSpriteWorld( spriteTestP->spriteWorldP );
  338.     SWAnimateSpriteWorld( spriteTestP->spriteWorldP );
  339. }
  340.  
  341.  
  342. /******************** UpdateSpriteTest ********************/
  343. void UpdateSpriteTest(
  344.     SpriteTestPtr spriteTestP,
  345.     WindowPtr updateWindowP)
  346. {
  347.     SetPort( updateWindowP );
  348.     if ( updateWindowP->portRect.right - updateWindowP->portRect.left > 
  349.         spriteTestP->spriteWorldP->backRect.right - 
  350.         spriteTestP->spriteWorldP->backRect.left )
  351.     {
  352.         ForeColor( blueColor );
  353.         PaintRect( &updateWindowP->portRect );
  354.     }
  355.     ForeColor( blackColor );
  356.     SWUpdateSpriteWorld(spriteTestP->spriteWorldP, true);
  357. }
  358.  
  359.  
  360. /******************** HandleCreateSpriteCommand ********************/
  361. void HandleCreateSpriteCommand(
  362.     SpriteTestPtr spriteTestP)
  363. {
  364.     OSErr err;
  365.     SpritePtr globeSpriteP;
  366.     Rect moveBoundsRect;
  367.     Point mouseLocation;
  368.  
  369.  
  370.     err = SWCloneSprite(gMasterGlobeSprite, &globeSpriteP, NULL);
  371.  
  372.     if (err == noErr)
  373.     {
  374.         moveBoundsRect = spriteTestP->spriteWorldP->backRect;
  375.         GetMouse(&mouseLocation);
  376.         mouseLocation.h -= spriteTestP->spriteWorldP->windRect.left;
  377.         mouseLocation.v -= spriteTestP->spriteWorldP->windRect.top;
  378.         
  379.         SetupGlobeSprite(globeSpriteP, &moveBoundsRect, mouseLocation.h, mouseLocation.v);
  380.  
  381.         SWAddSprite(spriteTestP->globeSpriteLayerP, globeSpriteP);
  382.     }
  383. }
  384.  
  385.  
  386. /******************** HandleSpriteTestTitleCommand ********************/
  387. void HandleSpriteTestTitleCommand(
  388.     SpriteTestPtr spriteTestP)
  389. {
  390.     gTitleVisible = !gTitleVisible;
  391.  
  392.     SWSetSpriteVisible(spriteTestP->titleSpriteP, gTitleVisible);
  393.     SWSetSpriteVisible(spriteTestP->twoSpriteP, gTitleVisible);
  394. }
  395.  
  396.  
  397. /******************** HandleBouncingBallsCommand ********************/
  398. void HandleBouncingBallsCommand(
  399.     SpriteTestPtr spriteTestP)
  400. {
  401.     SpritePtr globeSpriteP;
  402.     
  403.     
  404.     gGlobesVisible = !gGlobesVisible;
  405.  
  406.     globeSpriteP = NULL;
  407.     while ((globeSpriteP = SWGetNextSprite(spriteTestP->globeSpriteLayerP, globeSpriteP)) != NULL)
  408.     {
  409.         if (globeSpriteP != spriteTestP->titleSpriteP && globeSpriteP != spriteTestP->twoSpriteP)
  410.         {
  411.             SWSetSpriteVisible(globeSpriteP, gGlobesVisible);
  412.         }
  413.     }
  414. }
  415.  
  416.  
  417. /******************** RemoveClickedSprite ********************/
  418. void RemoveClickedSprite(
  419.     SpriteTestPtr spriteTestP)
  420. {
  421.     Point         mouseLocation;
  422.     SpritePtr    spriteToRemove;
  423.     
  424.     
  425.     if ( spriteTestP != NULL )
  426.     {
  427.         GetMouse(&mouseLocation);
  428.         
  429.         mouseLocation.h -= spriteTestP->spriteWorldP->windRect.left;
  430.         mouseLocation.v -= spriteTestP->spriteWorldP->windRect.top;
  431.             // if a sprite has been clicked on, and it isn't the title sprite,
  432.             // then remove it and dispose of it
  433.         spriteToRemove = SWFindSpriteByPoint(spriteTestP->globeSpriteLayerP, NULL, mouseLocation);
  434.         if ( spriteToRemove != NULL &&
  435.             spriteToRemove != spriteTestP->titleSpriteP &&
  436.             spriteToRemove != spriteTestP->twoSpriteP)
  437.         {
  438.             SWRemoveSpriteFromAnimation( spriteTestP->spriteWorldP, spriteToRemove, true );
  439.         }
  440.     }
  441. }
  442.  
  443.  
  444. /******************** SetUpTestDialog ********************/
  445. void SetUpTestDialog(
  446.     SpriteTestPtr spriteTestP)
  447. {
  448.     GrafPtr            savePort;
  449.     DialogPtr        theDialog;
  450.     short            itemHit;
  451.     ProcType        originalSpriteProc, 
  452.                     originalOffscreenProc,
  453.                     originalScreenProc;
  454.     Boolean            runNow;
  455.     Boolean            done = false;
  456.     OSErr            err = noErr;
  457.     
  458.  
  459.     GetPort( &savePort );
  460.         
  461.     theDialog = GetNewDialog(kSetUpTestResID, nil, (WindowPtr)-1L);
  462.         
  463.     SetDialogDefaultItem( theDialog, ok );
  464.     SetDialogCancelItem( theDialog, cancel );
  465.     
  466.     originalSpriteProc = gWhichSpriteProc;
  467.     originalOffscreenProc = gWhichOffscreenProc;
  468.     originalScreenProc = gWhichScreenProc;
  469.                 
  470.         // Check if we can do 8-bit-specific tests 
  471.     SetDItemHilite( theDialog, kCompiledSpriteButton, 
  472.             (spriteTestP->spriteWorldP->pixelDepth==8) );
  473. #if SW_PPC    
  474.     SetDItemHilite( theDialog, kBlitPixieSpriteButton, 
  475.             (spriteTestP->spriteWorldP->pixelDepth==8) );
  476.     SetDItemHilite( theDialog, kBlitPixieOffscreenButton, 
  477.             (spriteTestP->spriteWorldP->pixelDepth==8) );
  478.     SetDItemHilite( theDialog, kBlitPixieScreenButton, 
  479.             (spriteTestP->spriteWorldP->pixelDepth==8) );
  480.  
  481.     SetDItemHilite( theDialog, kCompiledSpriteButton, false );
  482. #endif
  483.  
  484.     SetCtlValue( (ControlHandle)GetDItemHdl(theDialog, kRunTestNowCheckBox), true );
  485.     
  486.     SetSetUpTestButtons( theDialog );
  487.     
  488.     ShowWindow( theDialog );
  489.     
  490.     while ( !done )
  491.     {    
  492.         ModalDialog( nil, &itemHit );
  493.         switch( itemHit )
  494.         {
  495.             case kCopyBitsSpriteButton:
  496.                 gWhichSpriteProc = kCopyBitsProc;
  497.                 SetSetUpTestButtons( theDialog );
  498.             break;
  499.             case kBlitPixieSpriteButton:
  500.                 gWhichSpriteProc = kBlitPixieProc;
  501.                 SetSetUpTestButtons( theDialog );
  502.             break;
  503.             case kCompiledSpriteButton:
  504.                 gWhichSpriteProc = kCompiledProc;
  505.                 SetSetUpTestButtons( theDialog );
  506.             break;
  507.             case kCopyBitsOffscreenButton:
  508.                 gWhichOffscreenProc = kCopyBitsProc;
  509.                 SetSetUpTestButtons( theDialog );
  510.             break;
  511.             case kBlitPixieOffscreenButton:
  512.                 gWhichOffscreenProc = kBlitPixieProc;
  513.                 SetSetUpTestButtons( theDialog );
  514.             break;
  515.             case kCopyBitsScreenButton:
  516.                 gWhichScreenProc = kCopyBitsProc;
  517.                 SetSetUpTestButtons( theDialog );
  518.             break;
  519.             case kBlitPixieScreenButton:
  520.                 gWhichScreenProc = kBlitPixieProc;
  521.                 SetSetUpTestButtons( theDialog );
  522.             break;
  523.             case kRunTestNowCheckBox:
  524.                 ToggleDItemValue(theDialog, kRunTestNowCheckBox);
  525.             break;
  526.             case ok:
  527.                 runNow = GetCtlValue( (ControlHandle)GetDItemHdl(theDialog, kRunTestNowCheckBox));
  528.             case cancel:
  529.                 done = true;
  530.             break;
  531.         }
  532.     }
  533.     DisposDialog( theDialog );
  534.     SetPort( savePort );
  535.     
  536.     if ( itemHit == ok )
  537.     {
  538.         if ( runNow )
  539.             RunTheTest( spriteTestP );
  540.     }
  541.     if ( itemHit == cancel )
  542.     {
  543.         gWhichSpriteProc = originalSpriteProc;
  544.         gWhichOffscreenProc = originalOffscreenProc;
  545.         gWhichScreenProc = originalScreenProc;
  546.     }
  547. }
  548.  
  549.  
  550.  
  551. /******************** SetSetUpTestButtons ********************/
  552. void SetSetUpTestButtons(
  553.     DialogPtr theDialog)
  554. {
  555.     SetCtlValue( (ControlHandle)GetDItemHdl(theDialog, kCopyBitsSpriteButton), 
  556.         (gWhichSpriteProc == kCopyBitsProc) );
  557.     SetCtlValue( (ControlHandle)GetDItemHdl(theDialog, kBlitPixieSpriteButton), 
  558.         (gWhichSpriteProc == kBlitPixieProc) );
  559.     SetCtlValue( (ControlHandle)GetDItemHdl(theDialog, kCompiledSpriteButton), 
  560.         (gWhichSpriteProc == kCompiledProc) );
  561.     
  562.     SetCtlValue( (ControlHandle)GetDItemHdl(theDialog, kCopyBitsOffscreenButton), 
  563.         (gWhichOffscreenProc == kCopyBitsProc) );
  564.     SetCtlValue( (ControlHandle)GetDItemHdl(theDialog, kBlitPixieOffscreenButton), 
  565.         (gWhichOffscreenProc == kBlitPixieProc) );
  566.     
  567.     SetCtlValue( (ControlHandle)GetDItemHdl(theDialog, kCopyBitsScreenButton), 
  568.         (gWhichScreenProc == kCopyBitsProc) );
  569.     SetCtlValue( (ControlHandle)GetDItemHdl(theDialog, kBlitPixieScreenButton), 
  570.         (gWhichScreenProc == kBlitPixieProc) );
  571. }
  572.  
  573.  
  574. /******************** RunTheTest ********************/
  575. void RunTheTest(
  576.     SpriteTestPtr spriteTestP)
  577. {
  578.     WindowPtr         testWindowP = FrontWindow();
  579.     SpritePtr         curSpriteP;
  580.     unsigned long     frames, seconds;
  581.     long             ticks;
  582.     Rect            shieldRect;
  583.     Point            shieldRectOffset;
  584.     Rect            srcRect,
  585.                     destRect;
  586.     UnsignedWide    startMicroseconds,
  587.                     endMicroseconds;
  588.  
  589.  
  590.         // set up for the test
  591.     
  592.     shieldRect = spriteTestP->spriteWorldP->windowFrameP->frameRect;
  593.     LocalToGlobal( &topLeft(shieldRect) );
  594.     LocalToGlobal( &botRight(shieldRect) );
  595.     shieldRectOffset.h = shieldRectOffset.v = 0;
  596.     ShieldCursor( &shieldRect, shieldRectOffset );
  597.     
  598.     HideMenuBar(testWindowP);
  599.     
  600.     UpdateSpriteTest( spriteTestP, testWindowP );
  601.     
  602.     curSpriteP = NULL;
  603.     while ((curSpriteP = SWGetNextSprite(spriteTestP->globeSpriteLayerP, curSpriteP)) != NULL)
  604.     {
  605.         if (curSpriteP != spriteTestP->titleSpriteP && curSpriteP != spriteTestP->twoSpriteP)
  606.         {
  607.             SWSetSpriteFrameTime(curSpriteP, 0);
  608.             SWSetSpriteMoveTime(curSpriteP, 0);
  609.             switch ( gWhichSpriteProc )
  610.             {
  611.                 case kBlitPixieProc:
  612.                     if ( spriteTestP->spriteWorldP->pixelDepth == 8 )
  613.                         (void)SWSetSpriteDrawProc(curSpriteP, BlitPixie8BitMaskDrawProc);
  614.                     else
  615.                     {
  616. #if !SW_PPC
  617.                         (void)SWSetSpriteDrawProc(curSpriteP, BlitPixieAllBitMaskDrawProc);
  618. #endif
  619.                     }
  620.                 break;
  621.                 case kCompiledProc:
  622.                     (void)SWSetSpriteDrawProc(curSpriteP, CompiledSprite8BitDrawProc);
  623.                 break;
  624.             }
  625.         }
  626.     }
  627.     
  628.     if ( gWhichSpriteProc == kBlitPixieProc || gWhichSpriteProc == kCompiledProc )
  629.     {
  630.         if ( spriteTestP->spriteWorldP->pixelDepth == 8 )
  631.         {
  632.             (void)SWSetSpriteDrawProc(spriteTestP->titleSpriteP, BlitPixie8BitMaskDrawProc);
  633.             (void)SWSetSpriteDrawProc(spriteTestP->twoSpriteP, BlitPixie8BitMaskDrawProc);
  634.         }
  635.         else
  636.         {
  637. #if !SW_PPC
  638.             (void)SWSetSpriteDrawProc(spriteTestP->titleSpriteP, BlitPixieAllBitMaskDrawProc);
  639.             (void)SWSetSpriteDrawProc(spriteTestP->twoSpriteP, BlitPixieAllBitMaskDrawProc);    
  640. #endif
  641.         }
  642.     }
  643.     if ( gWhichOffscreenProc == kBlitPixieProc )
  644.     {
  645.         if ( spriteTestP->spriteWorldP->pixelDepth == 8 )
  646.         {
  647.             (void)SWSetSpriteWorldOffscreenDrawProc(spriteTestP->spriteWorldP, 
  648.                 BlitPixie8BitRectDrawProc);
  649.         }
  650.         else
  651.         {
  652. #if !SW_PPC
  653.             (void)SWSetSpriteWorldOffscreenDrawProc(spriteTestP->spriteWorldP, 
  654.                 BlitPixieAllBitRectDrawProc);    
  655. #endif
  656.         }
  657.     }
  658.     if ( gWhichScreenProc == kBlitPixieProc )
  659.     {
  660.         if ( spriteTestP->spriteWorldP->pixelDepth == 8 )
  661.         {
  662.             (void)SWSetSpriteWorldScreenDrawProc(spriteTestP->spriteWorldP, 
  663.                 BlitPixie8BitRectDrawProc);
  664.         }
  665.         else
  666.         {
  667. #if !SW_PPC
  668.             (void)SWSetSpriteWorldOffscreenDrawProc(spriteTestP->spriteWorldP, 
  669.                 BlitPixieAllBitRectDrawProc);    
  670. #endif
  671.         }
  672.     }
  673.  
  674.         // Floor it!!!
  675.     SWSetSpriteWorldMaxFPS( spriteTestP->spriteWorldP, 0 );
  676.     
  677.     ticks = TickCount();
  678.  
  679.  
  680.         // the actual tests...
  681.         
  682.         // a straight blitter test -- no animation to screen
  683.  
  684.     if ( kBlitterTest && spriteTestP->spriteWorldP->pixelDepth == 8 )
  685.     {
  686.         srcRect = gMasterGlobeSprite->frameArray[0]->frameRect;
  687.         destRect = srcRect;
  688.         OffsetRect( &destRect, 3, 0 );
  689.         Microseconds( &startMicroseconds );
  690.         for (frames = 0; frames < 10000; frames++ )
  691.         {
  692.             BlitPixie8BitRectDrawProc(
  693.                 gMasterGlobeSprite->frameArray[0],
  694.                 spriteTestP->spriteWorldP->workFrameP,
  695.                 &srcRect,
  696.                 &destRect);
  697.         }
  698.         Microseconds( &endMicroseconds );
  699.         seconds = endMicroseconds.lo - startMicroseconds.lo;
  700.         if ( endMicroseconds.hi != startMicroseconds.hi )
  701.             seconds = 0;        // do test over
  702.     }
  703.         // a test of animation to screen
  704.     else
  705.     {
  706. /*
  707.         ProfilerSetStatus( true );
  708. */
  709.         for (frames = 0; ((TickCount() - ticks) < kTestTime) && (!Button()); frames++)
  710.         {
  711.             if (gCollisionDetection)
  712.             {
  713.                 SWCollideSpriteLayer(spriteTestP->spriteWorldP, 
  714.                     spriteTestP->globeSpriteLayerP, spriteTestP->globeSpriteLayerP);
  715.             }
  716.  
  717.             SWProcessSpriteWorld( spriteTestP->spriteWorldP );
  718.             SWAnimateSpriteWorld( spriteTestP->spriteWorldP );
  719.         }
  720.         seconds = ((TickCount() - ticks) / 60);
  721.     }
  722. /*
  723.     ProfilerSetStatus( false );
  724.     ProfilerDump( "\pSWPPC Profile" );
  725.     ProfilerTerm();
  726. */
  727.  
  728.         // restore things to default state
  729.     RestoreFromTest( testWindowP, spriteTestP );
  730.     
  731.     DisplayPerformance(frames, seconds);
  732. }
  733.  
  734.  
  735.  
  736. /******************** RestoreFromTest ********************/
  737. void RestoreFromTest(
  738.     WindowPtr testWindowP,
  739.     SpriteTestPtr spriteTestP)
  740. {
  741.     SpritePtr             curSpriteP;
  742.     
  743.     
  744.         // restore things to default state
  745.         
  746.     curSpriteP = NULL;
  747.  
  748.     while ((curSpriteP = SWGetNextSprite(spriteTestP->globeSpriteLayerP, curSpriteP)) != NULL)
  749.     {
  750.         (void)SWSetSpriteDrawProc(curSpriteP, SWStdSpriteDrawProc);
  751.         if (curSpriteP != spriteTestP->titleSpriteP && curSpriteP != spriteTestP->twoSpriteP)
  752.         {
  753.             SWSetSpriteFrameTime(curSpriteP, kGlobeSpriteFrameTime);
  754.         }
  755.     }
  756.     
  757.     (void)SWSetSpriteWorldOffscreenDrawProc(spriteTestP->spriteWorldP, SWStdWorldDrawProc);
  758.     (void)SWSetSpriteWorldScreenDrawProc(spriteTestP->spriteWorldP, SWStdWorldDrawProc);
  759.     
  760.     SWSetSpriteWorldMaxFPS( spriteTestP->spriteWorldP, 30 );
  761.     
  762.     ShowCursor();
  763.     ShowMenuBar(testWindowP);
  764. }
  765.  
  766.  
  767. /******************** DisplayPerformance ********************/
  768. void DisplayPerformance(
  769.     long frames,
  770.     long seconds)
  771. {
  772.     Str255 framesString, secondsString, fpsString;
  773.     long fps;
  774.     
  775.     NumToString(frames, framesString);
  776.     NumToString(seconds, secondsString);
  777.  
  778.     fps = (seconds > 0) ? frames / seconds : frames;
  779.     
  780.     NumToString(fps, fpsString);
  781.     
  782.     ParamText(framesString, secondsString, fpsString, "\p");
  783.     NoteAlert(kPerformanceAlertID, NULL);
  784. }
  785.  
  786.  
  787. /******************** TwoSpriteFrameProc ********************/
  788. void TwoSpriteFrameProc(SpritePtr twoSpriteP, FramePtr curFrameP,
  789.     long *frameIndex)
  790. {
  791.     if ( *frameIndex == 0 )
  792.         SWSetSpriteFrameAdvance( twoSpriteP, 1 );
  793.     else if ( *frameIndex == kNumberOfTwoFrames-1 )
  794.         SWSetSpriteFrameAdvance( twoSpriteP, -1 );
  795. }
  796.  
  797.  
  798. /******************** GlobeSpriteMoveProc ********************/
  799. void GlobeSpriteMoveProc(SpritePtr globeSpriteP)
  800. {    
  801.     SWOffsetSprite(globeSpriteP, globeSpriteP->horizMoveDelta, globeSpriteP->vertMoveDelta);
  802.     SWBounceSprite(globeSpriteP);
  803. }
  804.  
  805.  
  806. /******************** PixelBounceCollideProc ********************/
  807. void PixelBounceCollideProc(
  808.     SpritePtr srcSpriteP,
  809.     SpritePtr dstSpriteP,
  810.     Rect* sectRect)
  811. {    
  812.  
  813.         // If both sprites use the same collision routine (this one),ignore the second collision.
  814.     if ((!srcSpriteP->isVisible || !dstSpriteP->isVisible) ||
  815.         ((srcSpriteP->spriteCollideProc == dstSpriteP->spriteCollideProc) &&
  816.         (srcSpriteP > dstSpriteP)))
  817.     {
  818.         return;
  819.     }
  820.  
  821.     if ( SWPixelCollision(srcSpriteP, dstSpriteP) )
  822.     {
  823.             // if a stationary sprite (the title), just bounce off it
  824.         if ((dstSpriteP->horizMoveDelta == 0) && (dstSpriteP->vertMoveDelta == 0))
  825.         {
  826.             BounceGlobeOffTitle( dstSpriteP, srcSpriteP, sectRect );
  827.         }
  828.         else    
  829.             // globe to globe collision; swap movement delta's
  830.         {
  831.             BounceGlobeOffGlobe( srcSpriteP, dstSpriteP );
  832.         }
  833.     }
  834. }
  835.  
  836.  
  837. /******************** RegionBounceCollideProc ********************/
  838. void RegionBounceCollideProc(
  839.     SpritePtr srcSpriteP,
  840.     SpritePtr dstSpriteP,
  841.     Rect* sectRect)
  842. {    
  843.  
  844.         // If both sprites use the same collision routine (this one),ignore the second collision.
  845.     if ((!srcSpriteP->isVisible || !dstSpriteP->isVisible) ||
  846.         ((srcSpriteP->spriteCollideProc == dstSpriteP->spriteCollideProc) &&
  847.         (srcSpriteP > dstSpriteP)))
  848.     {
  849.         return;
  850.     }
  851.  
  852.  
  853.     if ( SWRegionCollision(srcSpriteP, dstSpriteP) )
  854.     {
  855.             // if a stationary sprite (the title), just bounce off it
  856.         if ((dstSpriteP->horizMoveDelta == 0) && (dstSpriteP->vertMoveDelta == 0))
  857.         {
  858.             BounceGlobeOffTitle( dstSpriteP, srcSpriteP, sectRect );
  859.         }
  860.         else    
  861.             // globe to globe collision; swap movement delta's
  862.         {
  863.             BounceGlobeOffGlobe( srcSpriteP, dstSpriteP );
  864.         }
  865.     }
  866. }
  867.  
  868.  
  869. /******************** RadiusBounceCollideProc ********************/
  870. void RadiusBounceCollideProc(
  871.     SpritePtr srcSpriteP,
  872.     SpritePtr dstSpriteP,
  873.     Rect* sectRect)
  874. {
  875.  
  876.         // If both sprites use the same collision routine (this one),ignore the second collision.
  877.     if ((!srcSpriteP->isVisible || !dstSpriteP->isVisible) ||
  878.         ((srcSpriteP->spriteCollideProc == dstSpriteP->spriteCollideProc) &&
  879.         (srcSpriteP > dstSpriteP)))
  880.         return;
  881.  
  882.         // ignore collision with title sprite
  883.     if ( (srcSpriteP->destFrameRect.right-srcSpriteP->destFrameRect.left !=
  884.          srcSpriteP->destFrameRect.bottom-srcSpriteP->destFrameRect.top) ||
  885.          (dstSpriteP->destFrameRect.right-dstSpriteP->destFrameRect.left !=
  886.          dstSpriteP->destFrameRect.bottom-dstSpriteP->destFrameRect.top))
  887.         return;
  888.  
  889.     if ( SWRadiusCollision( srcSpriteP, dstSpriteP ) )
  890.     {
  891.         BounceGlobeOffGlobe( srcSpriteP, dstSpriteP );
  892.     }
  893. }
  894.  
  895.  
  896. /******************** BounceGlobeOffGlobe ********************/
  897. void BounceGlobeOffGlobe(
  898.     SpritePtr srcSpriteP,
  899.     SpritePtr dstSpriteP )
  900. {
  901.     short            tempDelta;
  902.     short            nextHorizDistA, nextVertDistA,
  903.                     nextHorizDistB, nextVertDistB;
  904.  
  905.     
  906.         // reverse spins.
  907.     srcSpriteP->frameAdvance = -srcSpriteP->frameAdvance;
  908.     dstSpriteP->frameAdvance = -dstSpriteP->frameAdvance;
  909.  
  910.         // Calculate what the distance between sprites will be if we don't switch deltas
  911.     nextHorizDistA = srcSpriteP->destFrameRect.left + srcSpriteP->horizMoveDelta - 
  912.                 (dstSpriteP->destFrameRect.left + dstSpriteP->horizMoveDelta);
  913.     if (nextHorizDistA < 0)
  914.         nextHorizDistA = -nextHorizDistA;
  915.     
  916.     nextVertDistA = srcSpriteP->destFrameRect.top + srcSpriteP->vertMoveDelta - 
  917.                 (dstSpriteP->destFrameRect.top + dstSpriteP->vertMoveDelta);
  918.     if (nextVertDistA < 0)
  919.         nextVertDistA = -nextVertDistA;
  920.     
  921.         // Calculate what the distance between sprites will be if we do switch deltas
  922.     nextHorizDistB = srcSpriteP->destFrameRect.left + dstSpriteP->horizMoveDelta - 
  923.                 (dstSpriteP->destFrameRect.left + srcSpriteP->horizMoveDelta);
  924.     if (nextHorizDistB < 0)
  925.         nextHorizDistB = -nextHorizDistB;
  926.     
  927.     nextVertDistB = srcSpriteP->destFrameRect.top + dstSpriteP->vertMoveDelta - 
  928.                 (dstSpriteP->destFrameRect.top + srcSpriteP->vertMoveDelta);
  929.     if (nextVertDistB < 0)
  930.         nextVertDistB = -nextVertDistB;
  931.     
  932.     
  933.         // Will swapping the horizontal deltas move the sprites farther apart?
  934.     if (nextHorizDistB > nextHorizDistA)
  935.     {
  936.             // swap horizontal deltas
  937.         tempDelta = srcSpriteP->horizMoveDelta;
  938.         srcSpriteP->horizMoveDelta = dstSpriteP->horizMoveDelta;
  939.         dstSpriteP->horizMoveDelta = tempDelta;
  940.     }
  941.     
  942.         // Will swapping the vertical deltas move the sprites farther apart?
  943.     if (nextVertDistB > nextVertDistA)
  944.     {
  945.             // swap vertical deltas
  946.         tempDelta = srcSpriteP->vertMoveDelta;
  947.         srcSpriteP->vertMoveDelta = dstSpriteP->vertMoveDelta;
  948.         dstSpriteP->vertMoveDelta = tempDelta;
  949.     }
  950. }
  951.  
  952.  
  953.  /******************** BounceGlobeOffTitle ********************/
  954. void BounceGlobeOffTitle(
  955.     SpritePtr titleSpriteP,
  956.     SpritePtr globeSpriteP,
  957.     Rect* sectRect )
  958. {
  959.     short        absHorizDelta,
  960.                 absVertDelta;
  961.                 
  962.     absHorizDelta = globeSpriteP->horizMoveDelta;
  963.     if ( absHorizDelta < 0 )
  964.         absHorizDelta = -absHorizDelta;
  965.     absVertDelta = globeSpriteP->vertMoveDelta;
  966.     if ( absVertDelta < 0 )
  967.         absVertDelta = -absVertDelta;
  968.         
  969.     // draw a picture and this test algorithm will become clear
  970.     if ((sectRect->right - sectRect->left) < (sectRect->bottom - sectRect->top) )
  971.     {
  972.             // Hit left or right side
  973.         if ( sectRect->left <= titleSpriteP->destFrameRect.left )
  974.             // hit on left side
  975.             globeSpriteP->horizMoveDelta = -absHorizDelta;
  976.         else
  977.             // hit on right side
  978.             globeSpriteP->horizMoveDelta = absHorizDelta;
  979.     }
  980.     else
  981.     {
  982.             // Hit top or bottom
  983.         if ( sectRect->top <= titleSpriteP->destFrameRect.top )
  984.             // hit on top
  985.             globeSpriteP->vertMoveDelta = -absVertDelta;
  986.         else
  987.             // hit on bottom
  988.             globeSpriteP->vertMoveDelta = absVertDelta;
  989.     }
  990. }
  991.